package com.gmail.rusal4ica.logic;
import java.util.Random;

/**
 * @author The Imperial Sword Team
 */

public class DotsBot extends DotsGame {
	private static final int NUM_LINES_READY_TO_CLOSE = 3;
	private static final int NUM_LINES_FOR_NEXT_TRY = 2;

	private static final int AI_ALGORITHM_DEPTH = 120;

	private int countLines;
	private boolean openOnLeft;
	private boolean openOnRight;
	private boolean openOnAbove;
	private boolean openOnUnder;
	private int countTries;
	private int playedIndexN;
	private int playedIndexM;

	public DotsBot(int sizeN, int sizeM){
		super(sizeN, sizeM);
	}

	public void makeMove() {
		if(isGameOver()){
			return;
		} else {
			for (int i = 1; i < getDotsBoard().getBoard().length; i += 2) {
				for (int j = 1; j < getDotsBoard().getBoard()[0].length; j += 2) {
					countLines = 0;
					openOnLeft = false;
					openOnRight = false;
					openOnAbove = false;
					openOnUnder = false;
					if (getDotsBoard().getBoard()[i][j] == Board.FIELD_EMPTY) {
						// above
						if (getDotsBoard().getBoardCharAt(i - 1, j) == Board.LINE_FIELD_HORIZONTAL) {
							countLines++;
						} else
							openOnAbove = true;

						// under
						if (getDotsBoard().getBoardCharAt(i + 1, j) == Board.LINE_FIELD_HORIZONTAL) {
							countLines++;
						} else
							openOnUnder = true;
						// left
						if (getDotsBoard().getBoardCharAt(i, j - 1) == Board.LINE_FIELD_VERTICAL) {
							countLines++;
						} else
							openOnLeft = true;
						// right
						if (getDotsBoard().getBoardCharAt(i, j + 1) == Board.LINE_FIELD_VERTICAL) {
							countLines++;
						} else
							openOnRight = true;

						// move for closing a box

						if (countLines == NUM_LINES_READY_TO_CLOSE) {
							if (openOnAbove) {
								playDotsGame(i - 1, j);
								setPlayedIndexes(i - 1, j);
								return;
							}
							if (openOnUnder) {
								playDotsGame(i + 1, j);
								setPlayedIndexes(i + 1, j);
								return;
							}
							if (openOnLeft) {
								playDotsGame(i, j - 1);
								setPlayedIndexes(i, j - 1);
								return;
							}
							if (openOnRight) {
								playDotsGame(i, j + 1);
								setPlayedIndexes(i, j + 1);
								return;
							}
						}
					}
				}
			}

			makeRandomMove();
		}

	}

	private void makeRandomMove() {
		Random random = new Random();
		int randomI;
		int randomJ;
		countLines = 0;
		openOnLeft = false;
		openOnRight = false;
		openOnAbove = false;
		openOnUnder = false;
		do {
			do {
				randomI = random
						.nextInt(getDotsBoard().getBoard().length - 2) + 1;
			} while (randomI % 2 != 1);

			do {
				randomJ = random
						.nextInt(getDotsBoard().getBoard()[0].length - 2) + 1;
			} while (randomJ % 2 != 1);
		} while (getDotsBoard().getBoardCharAt(randomI, randomJ) != Board.FIELD_EMPTY);

		// above
		if (getDotsBoard().getBoardCharAt(randomI - 1, randomJ) == Board.LINE_FIELD_HORIZONTAL) {
			countLines++;
		} else
			openOnAbove = true;

		// under
		if (getDotsBoard().getBoardCharAt(randomI + 1, randomJ) == Board.LINE_FIELD_HORIZONTAL) {
			countLines++;
		} else
			openOnUnder = true;
		// left
		if (getDotsBoard().getBoardCharAt(randomI, randomJ - 1) == Board.LINE_FIELD_VERTICAL) {
			countLines++;
		} else
			openOnLeft = true;
		// right
		if (getDotsBoard().getBoardCharAt(randomI, randomJ + 1) == Board.LINE_FIELD_VERTICAL) {
			countLines++;
		} else
			openOnRight = true;

		if((countLines == NUM_LINES_FOR_NEXT_TRY) && (countTries < AI_ALGORITHM_DEPTH)) {
			countTries++;
			makeRandomMove();
			return;
		}
		countTries = 0;
		do {
			// Above
			if (openOnAbove) {
				if (random.nextBoolean()) {
					playDotsGame(randomI - 1, randomJ);
					setPlayedIndexes(randomI - 1, randomJ);
					return;
				}
			}
			// Under
			if (openOnUnder) {
				if (random.nextBoolean()) {
					playDotsGame(randomI + 1, randomJ);
					setPlayedIndexes(randomI + 1, randomJ);
					return;
				}
			}
			// left
			if (openOnLeft) {
				if (random.nextBoolean()) {
					playDotsGame(randomI, randomJ - 1);
					setPlayedIndexes(randomI, randomJ - 1);
					return;
				}
			}
			// Right
			if (openOnRight) {
				if (random.nextBoolean()) {
					playDotsGame(randomI, randomJ + 1);
					setPlayedIndexes(randomI, randomJ + 1);
					return;
				}
			}

		} while (true);

	}
	public int getPlayedIndexN() {
		return playedIndexN;
	}

	public int getPlayedIndexM() {
		return playedIndexM;
	}

	private void setPlayedIndexes(int i, int j) {
		this.playedIndexN = i;
		this.playedIndexM = j;
	}

}
